i2c: avoid getting stuck due to adaptive clocking #413
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When adaptive clocking is enabled, the MPSSE engine gets blocked waiting for the clock feedback signal to become high. This has a lot of side effects, breaking GPIO accesses, preventing further configuration commands from executing (including both 3-phase clocking as well as disabling adaptive clocking), and confusing the pyftdi read buffer.
The only way to recover seems to be purge the RX buffer, at which point the FTDI will process a "disable adaptive clocking" command.
To avoid getting caught in this condition, only enable adaptive clocking at the start of an I2C transaction and disable it at the end. This helps avoid any additional USB round-trips. If an I2C-related read fails to get any data (mainly when trying to read the ACK bit), assume the bus is wedged, and apply the workaround to ensure adaptive clocking is off until the next attempted I2C transaction.
Tested on an FT4232H. If the DUT is unpowered, GPIO get/set will work normally, and I2C transactions raise I2cIOError/"No answer from FTDI" (unchanged). Once the DUT becomes powered, I2C transactions immediately
work correctly.